/* compilo.l
 *
 *
 */

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ast.h"
#include "y.tab.h"

int num_lines=1;
%}

%option noyywrap
%x comment


boolean   ("true"|"false") 
nbr       (0|[1-9][0-9]*)   
blank     [ \t]+            
type      ("int"|"bool"|"iset"|"void")  
id        [a-zA-Z]([a-zA-Z]|[0-9])*     


%%

"{"             {BEGIN(comment);}
<comment>"}"    {BEGIN(INITIAL);}
<comment>"{"    {
                  fprintf(stderr,"KO\n");
                  printf("ERROR : invalid '%s' in line %d\n",yytext, num_lines);
                  exit(0);
                }
<comment>"\n"	{++num_lines;}
<comment>.      {/* skip the line */}


":"             {return SEMI_COL;}  /* semicolon */
":="            {return ASSIGN;}    /* assignation operator */
"write"         {return WRITE;}     /* write operation */
"read"          {return READ;}      /* read operation */
"="             {return EQUALS;}    /* equals operator */
"+"             {return PLUS;}      /* plus operator  for number*/
"-"             {return MINUS;}     /* minus operator for number*/
"*"             {return MULTIPLY;}  /* multiply operator for number*/
"/"             {return DIVIDE;}    /* divide operator for number */
"("             {return LP;}        /* left parentheses */
")"             {return RP;}        /* right parentheses */
"<"             {return LT;}        /* lower then operator for number*/
"<="            {return LE;}        /* lower then or equals operator for number */
"!"             {return NOT;}       /* not operator for boolean */
"||"            {return OR;}        /* or operator for boolean */
"&&"            {return AND;}       /* and operator for boolean */
"in"            {return IN;}        /* in operator for iset */
"min"           {return MIN;}       /* min operator for iset */
"max"			{return MAX;}       /* max operator for iset */
"#"				{return SHARP;}     /* count operator for iset */
"add"           {return ADD;}       /* add operation for iset from add x to iset */
"to"            {return TO;}        /* to : part of the add operation on iset */
"remove"        {return REMOVE;}    /* remove operation for iset from remove x from iset*/
"from"          {return FROM;}      /* from : part of the remove operation on iset */
"return"        {return RETURN;}    /* return operator */


"if"            {return IF;}        /* IF keyword for condition structure */
"then"          {return THEN;}      /* THEN keyword for condition structure */
"else"          {return ELSE;}      /* ELSE keyword for condition structure */
"fi"            {return FI;}        /* FI keyword to end condition structure */
"while"         {return WHILE;}     /* WHILE keyword of while loop */
"do"            {return DO;}        /* DO Keyword from the while loop structure */ 
"od"            {return OD;}        /* OD Keyword from the while loop structure */
"begin"         {return TAG_BEGIN;} 
"end"           {return TAG_END;}
"program"       {return PROG;}
"function"      {return FUNC;}
"var"           {return VAR;}
","             {return COMMA;}
";"             {return EOL;} 
"forward"       {return FORWARD;}

{boolean}   {
                if ( strcmp(yytext,"true") == 0 )
					yylval.bval=1;
				else
					yylval.bval=0;
                return BOOL;
            }


{nbr}        {
                yylval.ival=atoi(yytext);
                return NB;
             }


{type}      {
                if(strcmp(yytext, "void")==0) 
                    {yylval.ival=AT_VOID;}
                else
                {
                    if(strcmp(yytext, "int")==0) 
                        {yylval.ival=AT_NB;}
                    else
                    {
                        if(strcmp(yytext, "bool")==0)
                            {yylval.ival=AT_BOOL;}
                        else
                        {
                            if(strcmp(yytext, "iset")==0)
                                {yylval.ival=AT_ISET;}
                            else
                                {yylval.ival = AT_UNKNOWN;}
                        }
                    }
                }
                return TYPE;
            }

{id}        {
                yylval.sval=(char*)calloc(strlen(yytext)+1,sizeof(char));
                strcpy(yylval.sval,yytext);
                return ID;
            }




"\n"         {++num_lines;}

{blank}      {/*On passe*/}

.            {
                fprintf(stderr,"KO\n");
                printf("ERROR : invalid '%s' in line %d\n",yytext, num_lines);
                exit(0);
             }

%%
